package menu;

import static game.Configurations.SCREEN_HEIGHT;
import static game.Configurations.SCREEN_WIDTH;
import game.Controls;
import game.Controls.Key;
import game.FontLoader;
import static game.TextManager.t;
import images.MenuLoader;
import saves.SaveManager.Profile;
import static game.Controls.Key.*;
/**
 *
 * @author Luan
 */
public class SimpleMenu implements Menu {
    protected int itemCode;
    protected String name;
    
    protected int actionCode;
    /*
     * 0 - Load
     * 1 - Save
     * 2 - Use item
     * 3 - Put point on
     * 4 - Exit
     */
    
    protected Menu parent;
    
    protected FirstItem fi;
    protected SimpleMenuItem[] items;
    protected int selectedItem;
    protected Profile profile;
    
    public SimpleMenu(int itemCode, String name, FirstItem fi, SimpleMenuItem[] items) {
        this.itemCode = itemCode;
        this.name = name;
        this.fi = fi;
        this.items = items;
        this.selectedItem = 0;
        this.parent = null;
        
        this.actionCode = -1;
        this.profile = null;
        
        if (items != null)
            for (int i = 0; i < items.length; i++)
                if (items[i].son != null)
                    items[i].getSon().setParent(this);
    }
    
    @Override
    public Menu getParent() {
        return this.parent;
    }
    
    @Override
    public void setParent(Menu parent) {
        this.parent = parent;
    }
    
    @Override
    public void dispose() {}
    
    @Override
    public Menu zerar() {
        this.selectedItem = 0;
        if (this.fi != null)
            this.fi.selection = 0;
        return this;
    }
    
    @Override
    public Menu setProfile(Profile save) {
        this.profile = save;
        if (this.items != null && this.selectedItem >= this.items.length)
            this.selectedItem = this.items.length - 1;
        if (this.selectedItem < 0)
            this.selectedItem = 0;
        return this;
    }
    
    @Override
    public int getActionCode() {
        if (items.length == 0)
            return -1;
        if (items[selectedItem].getSubActionCode() != -1)
            return items[selectedItem].getSubActionCode();
        return this.actionCode;
    }

    public int getSelectedItem() {
        return selectedItem;
    }
        
    @Override
    public void draw() {
        int fih = (fi != null ? (fi.getHeight() + MenuLoader.getFiExtraHeight() + 5) : 0),
            dw = SCREEN_WIDTH - 10 - MenuLoader.getItemWidth(),
            s = 48;
        
        MenuLoader.bindTexture();
        MenuLoader.drawBack();
        MenuLoader.drawHolder(dw - 20, 10 + MenuLoader.getTitleHeight() + fih, (MenuLoader.getItemHeight() + 5)*items.length);
        MenuLoader.drawPointer(dw - 18, 18 + MenuLoader.getTitleHeight() + fih + (MenuLoader.getItemHeight() + 5)*selectedItem);
        MenuLoader.drawTitle();
        MenuLoader.drawIcon(itemCode, 10 + MenuLoader.getTitleHeight()/2 - s/2, 10 + MenuLoader.getTitleHeight()/2 - s/2, s);
        
        if (fi != null)
            MenuLoader.drawFI(dw, 10 + MenuLoader.getTitleHeight(), fi.getHeight());

        //First draw everything using the same texture        
        for (int i = 0; i < items.length; i++)
            items[i].draw(dw, 18 + MenuLoader.getTitleHeight() + fih + (MenuLoader.getItemHeight() + 5)*i, selectedItem == i);
        
        //Now write everything
        for (int i = 0; i < items.length; i++)
            items[i].write(dw, 18 + MenuLoader.getTitleHeight() + fih + (MenuLoader.getItemHeight() + 5)*i);
        FontLoader.MENU.drawString(10 + MenuLoader.getTitleHeight(), 10 + (MenuLoader.getTitleHeight() - FontLoader.MENU.getLineHeight())/2, name);
        
        //Finally draw the fi
        if (fi != null)
            fi.draw(dw, 10 + MenuLoader.getTitleHeight());
        
        writeActions();
    }
    
    //this method allows the sub classes to easily change the behaviour of the menu without performance losses
    protected void writeActions() {
        int y = SCREEN_HEIGHT - FontLoader.TEXT_BIG.getLineHeight();
        
        String t = "ESC - " + t().MENU_ACTIONS[0];
        FontLoader.TEXT_BIG.drawString(10, y, t);
        FontLoader.TEXT_BIG.drawString(40 + FontLoader.TEXT_BIG.getWidth(t), y, "Enter - " + t().MENU_ACTIONS[1]);
    }
    
    //to be overwritten
    public void quickAccess(int cod) {}
    
    @Override
    public void parse(int k, char c) {
        Key key = Controls.get(k, true);
        if (key == SEL_UP)
            moveV(false);
        else if (key == SEL_DOWN)
            moveV(true);

        if (key == SEL_LEFT)
            moveH(false);
        else if (key == SEL_RIGHT)
            moveH(true);

        if (key == GO_UP)
            moveCV(false);
        else if (key == GO_DOWN)
            moveCV(true);

        if (key == ZOOM_IN)
            moveCH(true);
        else if (key == ZOOM_OUT)
            moveCH(false);

        if (key == QA_0)
            quickAccess(0);
        else if (key == QA_1)
            quickAccess(1);
        else if (key == QA_2)
            quickAccess(2);
        else if (key == QA_3)
            quickAccess(3);
    }
    
    public void moveH(boolean right) {
        if (fi != null)
            fi.move(right);
    }
    
    public void moveV(boolean down) {
        if (down) {
            if (selectedItem < items.length - 1)
                selectedItem++;
        } else {
            if (selectedItem > 0)
                selectedItem--;
        }
    }

    public void moveCH(boolean right) {
        if (fi != null)
            fi.moveC(right);
    }

    public void moveCV(boolean down) {
        if (down)
            selectedItem = items.length - 1;
        else
            selectedItem = 0;
    }
    
    @Override
    public Menu go() {
        this.dispose();
        if (items.length == 0)
            return null;
        if (items[selectedItem].getSon() != null)
            return items[selectedItem].getSon().setProfile(profile);
        return null;
    }
    
    @Override
    public Menu back() {
        this.dispose();
        return parent;
    }
    
    public static class SimpleMenuItem {
        protected int itemCode;
        protected String text;
        protected Menu son;
        
        protected int subActionCode;
        
        public SimpleMenuItem(int itemCode, String text, Menu son) {
            this.itemCode = itemCode;
            this.text = text;
            this.son = son;
            
            this.subActionCode = -1;
        }

        public int getSubActionCode() {
            return subActionCode;
        }

        public void setSubActionCode(int subActionCode) {
            this.subActionCode = subActionCode;
        }
        
        public void draw(int x, int y, boolean sel) {
            MenuLoader.drawItem(x, y);
            MenuLoader.drawIcon(itemCode, x + 10, y + MenuLoader.getItemHeight()/2 - 16, 32);
        }
        
        public void write(int x, int y) {
            FontLoader.TEXT_BIG.drawString(x + 47, y + (MenuLoader.getItemHeight() - FontLoader.TEXT_BIG.getLineHeight())/2, text);
        }
        
        public Menu getSon() {
            return son;
        }
    }
    
    public abstract static class FirstItem {
        protected int selection, size;

        protected FirstItem(int size) {
            this.size = size;
            this.selection = 0;
        }
        
        public abstract void draw(int x, int y);
        public abstract int getHeight();
        
        public void move(boolean right) {
            if (right) {
                if (selection < size - 1)
                    selection++;
            } else {
                if (selection > 0)
                    selection--;
            }
        }
        
        public void moveC(boolean right) {
            if (right)
                selection = size - 1;
            else
                selection = 0;
        }
    }
}
